# -*- coding: utf-8 -*-

import cgi
import os

try:
    from hashlib import md5
except ImportError:
    from md5 import md5 

from django.utils import simplejson

import gdata.contacts.service
import gdata.alt.appengine
from gdata.service import BadAuthentication, CaptchaRequired
import twitter

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template

def compare_by(fieldname):
   def compare_two_dicts(a, b):
      return cmp(a[fieldname], b[fieldname])
   return compare_two_dicts


class MainPage(webapp.RequestHandler):
    def get(self):
        path = os.path.join(os.path.dirname(__file__), "index.html")
        self.response.out.write(template.render(path, {}))


class SyncContacts(webapp.RequestHandler):
    def set_response(self, code, message):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write(message)
        self.response.set_status(code, message=message)

    def test_parameters(self):
        self.parameters = cgi.FieldStorage()
        if not 'password' in self.parameters:
            self.set_response(400, 'Password required')
            return False
        if not 'username' in self.parameters:
            self.set_response(400, 'Username required')
            return False
        return True


class ContactsGmail(SyncContacts):
    client = None

    def login(self):
        
        if not self.test_parameters():
            return False
        
        self.client = gdata.contacts.service.ContactsService()
        gdata.alt.appengine.run_on_appengine(self.client)
        self.client.password = self.parameters['password'].value
        self.client.email = self.parameters['username'].value
        self.client.source = 'SprintWebApps-ContactsSync-1'
        self.client.auto_set_current_token = True
    
        try:
            if 'captcha_response' in self.parameters and \
               'captcha_token' in self.parameters:
                self.client.ProgrammaticLogin(
                    captcha_response=self.parameters['captcha_response'].value,
                    captcha_token=self.parameters['captcha_token'].value) 
            else:
                self.client.ProgrammaticLogin()
        except BadAuthentication:
            # TODO: más adelante usar 403
            self.set_response(401, 'Incorrect username or password')
            return False
        except CaptchaRequired:
            self.set_response(403, 'Captcha Required')
            self.response.clear()
            result = {}
            result['captcha_url'] = self.client.captcha_url
            result['captcha_token'] = self.client.captcha_token 
            self.response.out.write(simplejson.dumps(result))
            return False
        except Exception, e:
            self.set_response(400, e)
            return False
        return True
    
    def get(self):
        
        if not self.login():
            return
        
        query = gdata.contacts.service.ContactsQuery()
        query.max_results = 9999
        if 'start_index' in self.parameters:
            query.start_index = int(self.parameters['start_index'].value)

        feed = self.client.GetContactsFeed(query.ToUri())
        
        #self.response.headers['Content-Type'] = 'application/json'
        self.response.headers['Content-Type'] = 'text/plain'   # for DEBUG

        #token = self.client.GetClientLoginToken()

        if not feed.entry:
            self.response.out.write('[]')
        else:
            result = []
            for i, entry in enumerate(feed.entry):
                if entry.GetPhotoLink() is not None:
                    thumb = entry.GetPhotoLink().href
                else:
                    thumb = None
                result.append({
                   'email': ", ".join([email.address for email in entry.email]),
#                    [{'address': email.address,
#                     'type': 'primary' if email.primary else 'secondary'
#                    } for email in entry.email],
                   'name': "" if entry.title.text == None else entry.title.text,
                   'id': md5(entry.id.text).hexdigest(),
                   'thumb': thumb,
                   'service_id': entry.id.text
                   })
            self.response.out.write(
#                        simplejson.dumps(result.sort(compare_by('name'))))
                        simplejson.dumps(result))

class ContactsGmailThumnail(SyncContacts):
    client = None

    def login(self):
        
        if not self.test_parameters():
            return False
        
        self.client = gdata.contacts.service.ContactsService()
        gdata.alt.appengine.run_on_appengine(self.client)
        self.client.password = self.parameters['password'].value
        self.client.email = self.parameters['username'].value
        self.client.source = 'SprintWebApps-ContactsSync-1'
        self.client.auto_set_current_token = True
    
        try:
            if 'captcha_response' in self.parameters and \
               'captcha_token' in self.parameters:
                self.client.ProgrammaticLogin(
                    captcha_response=self.parameters['captcha_response'].value,
                    captcha_token=self.parameters['captcha_token'].value) 
            else:
                self.client.ProgrammaticLogin()
        except BadAuthentication:
            # TODO: más adelante usar 403
            self.set_response(401, 'Incorrect username or password')
            return False
        except CaptchaRequired:
            self.set_response(403, 'Captcha Required')
            self.response.clear()
            result = {}
            result['captcha_url'] = self.client.captcha_url
            result['captcha_token'] = self.client.captcha_token 
            self.response.out.write(simplejson.dumps(result))
            return False
        except Exception, e:
            self.set_response(400, e)
            return False
        return True
    
    def get(self):

        if not self.login():
            return

        if not 'service_id' in self.parameters:
            self.set_response(400, 'Service_id required')
            return False

        #self.response.headers['Content-Type'] = 'image/jpeg'
        self.response.headers['Content-Type'] = 'text/plain'   # for DEBUG
        print ""
        print "a"

        contact_entry = self.client.GetContact(
                            self.parameters['service_id'].value)
        hosted_image_binary = self.client.GetPhoto(contact_entry)
        print hosted_image_binary
        #self.response.out.write(hosted_image_binary)
        import StringIO

        output = StringIO.StringIO()
        output.write('First line.\n')
        print >>output, 'Second line.'
        
        # Retrieve file contents -- this will be
        # 'First line.\nSecond line.\n'
        contents = output.getvalue()
        
        # Close object and discard memory buffer -- 
        # .getvalue() will now raise an exception.
        output.close()

        
#        image_file = open('test.jpg', 'wb')
#        image_file.write(hosted_image_binary)
#        image_file.close()
    



class ContactsTwitter(SyncContacts):

    def get(self):
        if not self.test_parameters():
            return
        
        api = twitter.Api(username=self.parameters['username'].value, 
                          password=self.parameters['password'].value)
        try:
            users = api.GetFriends()
        except :
            self.set_response(401, 'Incorrect username or password')
            return False

        result = []
        for u in users:
            result.append({
                'id': u.id,
                'name': u.name,
                'thumb': u.profile_image_url
            })
        self.response.headers['Content-Type'] = 'application/json'
        self.response.out.write(simplejson.dumps(result))

application = webapp.WSGIApplication(
                                     [('/', MainPage),
                                      ('/contacts/gmail/', ContactsGmail),
                                      ('/contacts/gmail/get_thumnail/', ContactsGmailThumnail),
                                      ('/contacts/twitter/', ContactsTwitter)],
                                     debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
